home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / pcl / src-16f.lha / ldb / rt-arch.c < prev    next >
C/C++ Source or Header  |  1992-05-19  |  4KB  |  165 lines

  1. #include <stdio.h>
  2. #include <mach.h>
  3. #include <sys/file.h>
  4. #include <sys/types.h>
  5. #include <sys/mman.h>
  6.  
  7. #include "ldb.h"
  8. #include "lisp.h"
  9. #include "globals.h"
  10. #include "validate.h"
  11. #include "os.h"
  12. #include "arch.h"
  13. #include "lispregs.h"
  14. #include "signal.h"
  15.  
  16. #define FL_NONE 0
  17. #define FL_FPA 2
  18. #define FL_AFPA 4
  19. #define FL_MC68881 1
  20.  
  21. #define READ_MC68881_FPCR 0xfc3ec001
  22. #define WRITE_MC68881_FPCR 0xfc024001
  23. #define MC68881_ZIC 0xfc1c0003
  24. #define MC68881_PREC_MASK 0xff3f
  25. #define MC68881_DOUBLE_PREC 0x0080
  26.  
  27. /* This is only used during arch_init to find out what kind of FP we have. */
  28. static sigsys_handler(signal, code, scp)
  29. int signal, code;
  30. struct sigcontext *scp;
  31. {
  32.     return (-1);
  33. }
  34.  
  35. char *arch_init()
  36. {
  37.     int hw, i, rc;
  38.     int fs[5];
  39.     struct sigvec sv, osv;
  40.  
  41.     /* Set up the state of the floating point hardware.  On the APC, there is
  42.        the onboard MC68881 which must be dealt with properly.  The signal
  43.        handling is necessary to be compatible with facilities version
  44.        of Mach.  */
  45.  
  46.     sv.sv_handler = sigsys_handler;
  47.     sv.sv_mask = sigmask(SIGSYS);
  48.     sv.sv_onstack = FALSE;
  49.     rc = sigvec(SIGSYS, &sv, &osv);
  50.     i = 20;
  51.     rc = syscall(167, fs, &i);
  52.     if (rc == 0) {
  53.     i = fs[0];
  54.     hw = i & 7;
  55.     if (i & 1) {
  56.         *(int *)READ_MC68881_FPCR = (int) &i;
  57.         *(int *)MC68881_ZIC = 0;
  58.         i = ((i & MC68881_PREC_MASK) | MC68881_DOUBLE_PREC);
  59.         *(int *)WRITE_MC68881_FPCR = (int) &i;
  60.         if (i & 2)
  61.         hw = hw & (~2);
  62.     }
  63.     }
  64.     else
  65.     hw = FL_FPA;
  66.  
  67.     sigvec(SIGSYS, &osv, &sv);
  68.  
  69.     switch (hw) {
  70.       case FL_FPA:
  71.     fprintf(stderr, "CMUCL only supports the AFPA and the MC68881 floating point options.\n");
  72.     exit(1);
  73.       case FL_AFPA:
  74.     return "eapc.core";
  75.       case FL_MC68881:
  76.     return NULL;
  77.       default:
  78.     fprintf(stderr, "CMUCL only supports the AFPA and the MC68881 floating point options.\nUse a different machine.\n");
  79.     exit(1);
  80.     }
  81. }
  82.  
  83. os_vm_address_t arch_get_bad_addr(context)
  84. struct sigcontext *context;
  85. {
  86.     return 0;
  87. }
  88.  
  89. void arch_skip_instruction(context)
  90. struct sigcontext *context;
  91. {
  92.     unsigned long pc = context->sc_iar;
  93.     unsigned long prev_inst = ((unsigned long *)pc)[-1];
  94.  
  95.     if ((prev_inst >> 24) == 0x89) {
  96.     short offset = prev_inst & 0xffff;
  97.     context->sc_pc = pc - 4 + offset;
  98.     }
  99.     else
  100.     context->sc_pc = pc + 4;
  101. }
  102.  
  103. static sigtrap_handler(signal, code, context)
  104.      int signal, code;
  105.      struct sigcontext *context;
  106. {
  107.     switch (*((char *)context->sc_iar)) {
  108.       case 0xCC:
  109.     /* trap-immediate instruction. */
  110.     switch (*((unsigned short *)context->sc_iar+1)) {
  111.       case trap_PendingInterrupt:
  112.         interrupt_handle_pending(context);
  113.         break;
  114.  
  115.       case trap_Halt:
  116.         crap_out("%primitive halt called; the party is over.\n");
  117.  
  118.       case trap_Error:
  119.       case trap_Cerror:
  120.         interrupt_internal_error(signal, code, context, code==trap_Cerror);
  121.         break;
  122.  
  123.       case trap_Breakpoint:
  124.         sigsetmask(context->sc_mask);
  125.         fake_foreign_function_call(context);
  126.         handle_breakpoint(signal, code, context);
  127.         undo_fake_foreign_function_call(context);
  128.         break;
  129.  
  130.       case trap_FunctionEndBreakpoint:
  131.         sigsetmask(context->sc_mask);
  132.         fake_foreign_function_call(context);
  133.         handle_function_end_breakpoint(signal, code, context);
  134.         undo_fake_foreign_function_call(context);
  135.         break;
  136.  
  137.       default:
  138.         interrupt_handle_now(signal, code, context);
  139.         break;
  140.     }
  141.     break;
  142.  
  143.       case 0xBE:
  144.     /* Trap Less Than instruction. */
  145.     if (SymbolValue(ALLOCATION_POINTER)>SymbolValue(INTERNAL_GC_TRIGGER)) {
  146.         SetSymbolValue(INTERNAL_GC_TRIGGER, fixnum(-1));
  147.         interrupt_maybe_gc(context);
  148.         context->sc_iar += 2;
  149.     }
  150.     else
  151.         interrupt_handle_now(signal, code, context);
  152.     break;
  153.  
  154.       default:
  155.     interrupt_handle_now(signal, code, context);
  156.     break;
  157.     }
  158. }
  159.  
  160.  
  161. void arch_install_interrupt_handlers()
  162. {
  163.     interrupt_install_low_level_handler(SIGTRAP,sigtrap_handler);
  164. }
  165.